home *** CD-ROM | disk | FTP | other *** search
- /* Counter.C
- *
- * LameTeX needs to keep track of a number of counters, just like LaTeX does,
- * for things like tables, footnotes, chapters and sections, and enumerations.
- * Since all counters need to be handled in much the same way, the Counter
- * derived class under the Parameters class has been defined.
- *
- * Copyright 1992 Jonathan Monsarrat. Permission given to freely distribute,
- * edit and use as long as this copyright statement remains intact.
- *
- */
-
- #include "Operator.h"
- #include "Global.h"
- #include "Counter.h"
- #include "Document.h"
- #include "Font.h"
- #include <string.h>
- #include <stdio.h>
-
- Counter::Counter()
- {
- for(int x=0; x < LastType; x++)
- counters[x] = 0;
- }
-
- Counter::Counter(Counter *base)
- {
- for(int x=0; x < LastType; x++)
- counters[x] = base->counters[x];
- }
-
- Param *Counter::copy()
- {
- return new Counter(this);
- }
-
- int Counter::set(int subtype, float print_number, char *)
- {
- char number[10];
- char message[20];
- char output[20];
- if(subtype >= Part && subtype <= Subparagraph) {
- Token openbrace;
- if(!openbrace.match("{"))
- Global::files->fatal_error("Expecting '{' after section statement");
- if(print_number) {
- counters[subtype]++;
- switch(subtype) {
- case Part:
- counters[Chapter]=0;
- case Chapter:
- counters[Section]=0;
- case Section:
- counters[Subsection]=0;
- case Subsection:
- counters[Subsubsection]=0;
- case Subsubsection:
- counters[Paragraph]=0;
- case Paragraph:
- counters[Subparagraph]=0;
- case Subparagraph:
- default:
- break;
- }
- } else
- counters[subtype] = -1;
- }
-
- float fontsize = Global::stack->get(Environment::PFont, Font::Size, "");
-
- switch(subtype) {
- case Part:
- Global::files->outfile << endl;
- if(print_number) {
- Operator::plaintext("Part");
- upcase_roman(counters[Part], number);
- Operator::plaintext(number);
- }
- Operator::do_vspace(0, 0, 200.0, "");
- break;
- case Chapter:
- Global::files->outfile << endl;
- if(Global::files->plain_text_output)
- Operator::do_vspace(0, 0, 13.0, "");
- else
- Operator::do_vspace(0, 0, 112.5 + (fontsize-18.0) * 0.85, "");
- if(print_number) {
- Operator::plaintext("Chapter");
- arabic(counters[Chapter], number);
- Operator::plaintext(number);
-
- if(Global::files->plain_text_output)
- Operator::do_vspace(0, 0, 13.0, "");
- else
- Operator::do_vspace(0, 0, 50.0 + (fontsize-22.0) * 0.85, "");
- }
- Stack::set(Environment::PFont, Font::Huge, 0.0, "");
- break;
- case Section:
- Global::files->outfile << endl;
- if(Global::files->plain_text_output)
- Operator::do_vspace(0, 0, 8.0, "");
- else
- Operator::do_vspace(0, 0, 20.7 + (fontsize-13.0) * 3.4, "");
- if(print_number) {
- sprintf(number,"%d.%d",counters[Chapter],counters[Section]);
- Operator::plaintext(number);
- Global::files->outfile << endl;
- Global::files->outfile << 15.0 + (fontsize-13.0) * 1.1
- << " HSpace" << endl;
- }
- break;
- case Subsection:
- Global::files->outfile << endl;
- Operator::do_vspace(0, 0, 4.5 + (fontsize-11.0) * 3.4, "");
- if(print_number) {
- sprintf(number,"%d.%d.%d",counters[Chapter],counters[Section],
- counters[Subsection]);
- Operator::plaintext(number);
- Global::files->outfile << endl;
- Global::files->outfile << 15.0 + (fontsize-11.0) * 1.1
- << " HSpace" << endl;
- }
- break;
- case Subsubsection:
- case Paragraph:
- case Subparagraph:
- break;
- case Page:
- break;
- case Equation:
- break;
- case Figure:
- break;
- case Table:
- break;
- case Footnote:
- break;
- case Mpfootnote:
- break;
- case Description:
- counters[Item] = Description; // Mark Description most recent
- counters[Description]=0;
- break;
- case Itemize:
- counters[Item] = Itemize; // Mark Itemize most recent
- break;
- case Enum:
- if(++counters[Enum] > 4)
- Global::files->fatal_error(
- "Can't have more than four nested enumerates");
- counters[Item] = Enum; // Mark Enumerate most recent
- switch(counters[Enum]) {
- case 1:
- counters[Enumi]=0;
- break;
- case 2:
- counters[Enumii]=0;
- break;
- case 3:
- counters[Enumiii]=0;
- break;
- case 4:
- counters[Enumiv]=0;
- break;
- }
- break;
- case Enumi:
- break;
- case Enumii:
- break;
- case Enumiii:
- break;
- case Enumiv:
- break;
- case Item:
- switch(counters[Item]) {
- case Description:
- description();
- break;
- case Itemize:
- Stack::set(Environment::PDocument, Document::NewLine, 0.0, "");
- Global::files->force_start_page();
- Global::files->outfile << endl;
- Global::files->outfile << "BULLET" << endl;
- break;
- case Enum:
- Stack::set(Environment::PDocument, Document::NewLine, 0.0, "");
- Global::files->force_start_page();
- Global::files->outfile << endl;
- switch(counters[Enum]) {
- case 1:
- arabic(++counters[Enumi], message);
- strcat(message, ".");
- break;
- case 2:
- message[0]='(';
- downcase_alpha(++counters[Enumii], &message[1]);
- strcat(message, ")");
- break;
- case 3:
- downcase_roman(++counters[Enumiii], message);
- strcat(message, ".");
- break;
- case 4:
- upcase_alpha(++counters[Enumiv], message);
- strcat(message, ".");
- break;
- }
- Global::files->force_start_page();
- Operator::registrar(message, output);
- Global::files->outfile << " " << output << " ENUMERATE" << endl;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return TRUE;
- }
-
- /* Handles the \item command in a description. If the item is the 0th
- * item, then make an indentation.
- */
- void Counter::description()
- {
- Stack::relative_set(Environment::PLength, Length::Parameter,
- -22.5, "\\oddsidemargin");
- Stack::relative_set(Environment::PLength, Length::Parameter,
- 22.5, "\\textwidth");
- Stack::set(Environment::PDocument, Document::NewLine, 0.0, "");
- Global::files->force_start_page();
- Global::files->outfile << endl;
-
- Token openbrace;
- if(!openbrace.match("["))
- Global::files->fatal_error("Expecting '[' after \\item");
- Stack::set(Environment::PFont, Font::Bold, 0.0, "");
-
- for(Token description; !description.match("]"); description=Token())
- description.handle();
-
- Global::files->outfile << endl << "13.0 HSpace" << endl;
- Stack::set(Environment::PFont, Font::Roman, 0.0, "");
-
- Stack::relative_set(Environment::PLength, Length::Parameter,
- 22.5, "\\oddsidemargin");
- Stack::relative_set(Environment::PLength, Length::Parameter,
- -22.5, "\\textwidth");
- }
-
- float Counter::get(int subtype, char *)
- {
- return counters[subtype];
- }
-
- void Counter::postscript_set(int subtype)
- {
- switch(subtype) {
- default:
- break;
- }
- }
-
- void Counter::revert(Param *from)
- {
- int count;
- for(int subtype=0; subtype < LastType; subtype++)
- if((count = (int)from->get(subtype,"revert")) != counters[subtype]) {
- if(count > 0)
- counters[subtype] = count;
- switch(subtype) {
- case Part:
- Stack::set(Environment::PDocument, Document::NewLine, 0.0, "");
- case Chapter:
- if(Global::files->plain_text_output)
- Operator::do_vspace(0, 0, 13.0, "");
- else
- Operator::do_vspace(0, 0, 52, "");
- break;
- case Section:
- if(Global::files->plain_text_output)
- Operator::do_vspace(0, 0, 8.0, "");
- else
- Operator::do_vspace(0, 0, 22.4, "");
- break;
- case Subsection:
- if(Global::files->plain_text_output)
- Operator::do_vspace(0, 0, 8.0, "");
- else
- Operator::do_vspace(0, 0, 18.0, "");
- break;
- case Subsubsection:
- case Paragraph:
- case Subparagraph:
- Stack::set(Environment::PDocument, Document::NewLine, 0.0, "");
- break;
- case Page:
- break;
- case Equation:
- break;
- case Figure:
- break;
- case Table:
- break;
- case Footnote:
- break;
- case Mpfootnote:
- break;
- case Enum:
- counters[Enum]--;
- break;
- case Enumi:
- break;
- case Enumii:
- break;
- case Enumiii:
- break;
- case Enumiv:
- break;
- case Itemize:
- break;
- }
- }
- }
-
- void Counter::downcase_roman(int count, char *number)
- {
- switch(count/100) {
- case 1:
- strcpy(number,"c");
- break;
- case 2:
- strcpy(number,"cc");
- break;
- case 3:
- strcpy(number,"ccc");
- break;
- case 4:
- strcpy(number,"cd");
- break;
- case 5:
- strcpy(number,"d");
- break;
- case 0:
- default:
- strcpy(number,"");
- break;
- }
-
- switch(count%100/10) {
- case 0:
- break;
- case 1:
- strcat(number,"x");
- break;
- case 2:
- strcat(number,"xx");
- break;
- case 3:
- strcat(number,"xxx");
- break;
- case 4:
- strcat(number,"xl");
- break;
- case 5:
- strcat(number,"l");
- break;
- case 6:
- strcat(number,"lx");
- break;
- case 7:
- strcat(number,"lxx");
- break;
- case 8:
- strcat(number,"lxxx");
- break;
- case 9:
- strcat(number,"xc");
- break;
- }
-
- switch(count%10) {
- case 0:
- break;
- case 1:
- strcat(number,"i");
- break;
- case 2:
- strcat(number,"ii");
- break;
- case 3:
- strcat(number,"iii");
- break;
- case 4:
- strcat(number,"iv");
- break;
- case 5:
- strcat(number,"v");
- break;
- case 6:
- strcat(number,"vi");
- break;
- case 7:
- strcat(number,"vii");
- break;
- case 8:
- strcat(number,"viii");
- break;
- case 9:
- strcat(number,"ix");
- break;
- }
- };
-
- void Counter::upcase_roman(int count, char *number)
- {
- switch(count/100) {
- case 1:
- strcpy(number,"C");
- break;
- case 2:
- strcpy(number,"CC");
- break;
- case 3:
- strcpy(number,"CCC");
- break;
- case 4:
- strcpy(number,"CD");
- break;
- case 5:
- strcpy(number,"D");
- break;
- case 0:
- default:
- strcpy(number,"");
- break;
- }
-
- switch(count%100/10) {
- case 0:
- break;
- case 1:
- strcat(number,"X");
- break;
- case 2:
- strcat(number,"XX");
- break;
- case 3:
- strcat(number,"XXX");
- break;
- case 4:
- strcat(number,"XL");
- break;
- case 5:
- strcat(number,"L");
- break;
- case 6:
- strcat(number,"LX");
- break;
- case 7:
- strcat(number,"LXX");
- break;
- case 8:
- strcat(number,"LXXX");
- break;
- case 9:
- strcat(number,"XC");
- break;
- }
-
- switch(count%10) {
- case 0:
- break;
- case 1:
- strcat(number,"I");
- break;
- case 2:
- strcat(number,"II");
- break;
- case 3:
- strcat(number,"III");
- break;
- case 4:
- strcat(number,"IV");
- break;
- case 5:
- strcat(number,"V");
- break;
- case 6:
- strcat(number,"VI");
- break;
- case 7:
- strcat(number,"VII");
- break;
- case 8:
- strcat(number,"VIII");
- break;
- case 9:
- strcat(number,"IX");
- break;
- }
- };
-
- void Counter::arabic(int count, char *number)
- {
- sprintf(number,"%d",count);
- };
-
- void Counter::downcase_alpha(int count, char *number)
- {
- if(count >= 26) {
- sprintf(number,"%c%c",('a'+count/26-1),('a'+count%26-1));
- }
- sprintf(number,"%c",('a'+count%26-1));
- };
-
- void Counter::upcase_alpha(int count, char *number)
- {
- if(count >= 26) {
- sprintf(number,"%c%c",('A'+count/26-1),('A'+count%26-1));
- }
- sprintf(number,"%c",('A'+count%26-1));
- };
-